package com.zxy.ziems.server.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zxy.btp.common.exception.ConditionException;
import com.zxy.btp.common.response.PageResult;
import com.zxy.ziems.server.constant.enums.DictItemStatusEnum;
import com.zxy.ziems.server.convert.DictItemConvert;
import com.zxy.ziems.server.domain.Dict;
import com.zxy.ziems.server.domain.DictItem;
import com.zxy.ziems.server.dto.DictItemDto;
import com.zxy.ziems.server.dto.DictItemQueryDto;
import com.zxy.ziems.server.mapper.DictItemMapper;
import com.zxy.ziems.server.service.DictItemService;
import com.zxy.ziems.server.service.DictService;
import com.zxy.ziems.server.utils.AssertUtil;
import com.zxy.ziems.server.utils.BusinessExceptionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName DictItemServiceImpl
 * @Description
 * @Author 邓伟
 * @Date 2023/11/22 15:53
 * @Version 1.0
 */
@Service
public class DictItemServiceImpl extends ServiceImpl<DictItemMapper, DictItem> implements DictItemService {

    @Autowired
    private DictItemMapper dictItemMapper;
    @Autowired
    private DictService dictService;

    @Override
    public PageResult<DictItem> pageList(DictItemQueryDto dictItemQueryDto) {
        Page<DictItem> page = dictItemMapper.selectPage(new Page<>(dictItemQueryDto.getPageNo(), dictItemQueryDto.getPageSize()),
                new QueryWrapper<DictItem>().lambda()
                        .like(StrUtil.isNotEmpty(dictItemQueryDto.getItemCode()), DictItem::getItemCode, dictItemQueryDto.getItemCode())
                        .like(StrUtil.isNotEmpty(dictItemQueryDto.getItemName()), DictItem::getItemName, dictItemQueryDto.getItemName())
                        .eq(StrUtil.isNotEmpty(dictItemQueryDto.getDictCode()), DictItem::getDictCode, dictItemQueryDto.getDictCode())
                        .orderByAsc(DictItem::getItemSort));
        return new PageResult<>(page.getTotal(), page.getRecords());
    }

    @Override
    public List<DictItem> list(DictItemQueryDto dictItemQueryDto) {
        return dictItemMapper.selectList(new QueryWrapper<DictItem>().lambda()
                .like(StrUtil.isNotEmpty(dictItemQueryDto.getItemName()), DictItem::getItemName, dictItemQueryDto.getItemName())
                .eq(DictItem::getDictCode, dictItemQueryDto.getDictCode())
                .orderByAsc(DictItem::getItemSort));
    }

    @Override
    public void addOrUpdate(DictItemDto dictItemDto) {
        String itemId = dictItemDto.getItemId();
        DictItem dictItem = DictItemConvert.INSTANCE.dictItemDtoToDictItem(dictItemDto);
        checkNameAndCode(dictItemDto);
        if (StrUtil.isEmpty(itemId)) {
            dictItem.setStatus(DictItemStatusEnum.START.code());
            dictItemMapper.insert(dictItem);
        } else {
            dictItemMapper.updateById(dictItem);
        }
    }

    @Override
    public Map<String, List<DictItem>> itemCollection() {
        Map<String, List<DictItem>> map = new HashMap<>();
        List<DictItem> itemList = dictItemMapper.selectList(null);
        return itemList.stream().collect(Collectors.groupingBy(DictItem::getDictCode));
    }

    @Override
    public void startOrStop(DictItemDto dictItemDto) {
        Integer status = dictItemDto.getStatus();
        if (ObjectUtil.isEmpty(status)) {
            throw new ConditionException("状态不能为空");
        }
        String itemId = dictItemDto.getItemId();
        if (StrUtil.isEmpty(itemId)) {
            throw new ConditionException("字典项id不能为空");
        }
        DictItem dictItem = new DictItem();
        dictItem.setItemId(itemId);
        dictItem.setStatus(status);
        dictItemMapper.updateById(dictItem);
    }

    private void checkNameAndCode(DictItemDto dictItemDto) {
        String itemId = dictItemDto.getItemId();
        QueryWrapper<DictItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().ne(StrUtil.isNotEmpty(itemId), DictItem::getItemId, itemId)
                .eq(DictItem::getItemName, dictItemDto.getItemName())
                .eq(DictItem::getDictCode, dictItemDto.getDictCode());
        Long count = dictItemMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new ConditionException("字典项名称不能重复，请修改");
        }
        queryWrapper.clear();
        queryWrapper.lambda().ne(StrUtil.isNotEmpty(itemId), DictItem::getItemId, itemId)
                .eq(DictItem::getItemCode, dictItemDto.getItemCode())
                .eq(DictItem::getDictCode, dictItemDto.getDictCode());
        Long countCode = dictItemMapper.selectCount(queryWrapper);
        if (countCode > 0) {
            throw new ConditionException("字典项编码不能重复，请修改");
        }
    }

    @Override
    public List<DictItem> getByDictCode(String code) {
        if (StrUtil.isEmpty(code)) {
            return new ArrayList<>();
        }
        QueryWrapper<Dict> query = new QueryWrapper<>();
        query.lambda().eq(Dict::getDictCode, code);
        Dict one = dictService.getOne(query);
        AssertUtil.nonNull(one, "未找到字典配置");

        QueryWrapper<DictItem> queryItem = new QueryWrapper<>();
        queryItem.lambda().eq(DictItem::getDictCode, one.getDictCode())
                .eq(DictItem::getStatus, 1)
                .orderByAsc(DictItem::getItemSort);
        List<DictItem> list = list(queryItem);
        if (CollectionUtil.isEmpty(list)) {
            throw BusinessExceptionUtil.exception("请确认配置项是否启用");
        }
        return list;
    }

    @Override
    public DictItem getByDictCodeAndItemName(String code, String itemName) {
        List<DictItem> itemList = getByDictCode(code);
        List<DictItem> collect = itemList.stream().filter(m -> m.getItemName().equals(itemName)).collect(Collectors.toList());
        return CollectionUtil.isEmpty(collect) ? null : collect.get(0);
    }
}
